/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package entidade.controller.JPA;

import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.controller.JPA.exceptions.RollbackFailureException;
import entidade.persistencia.Funcionario;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import entidade.persistencia.Usuario;
import entidade.persistencia.Manutencao;
import java.util.ArrayList;
import java.util.List;
import entidade.persistencia.Compra;
import entidade.persistencia.Venda;
import entidade.persistencia.FolhaPagamento;
import javax.transaction.UserTransaction;

/**
 *
 * @author victorinox
 */
public class FuncionarioJpaController {
    @Resource
    private UserTransaction utx = null;
    @PersistenceUnit(unitName = "globalimage2PU")
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Funcionario funcionario) throws RollbackFailureException, Exception {
        if (funcionario.getManutencaoCollection() == null) {
            funcionario.setManutencaoCollection(new ArrayList<Manutencao>());
        }
        if (funcionario.getCompraCollection() == null) {
            funcionario.setCompraCollection(new ArrayList<Compra>());
        }
        if (funcionario.getVendaCollection() == null) {
            funcionario.setVendaCollection(new ArrayList<Venda>());
        }
        if (funcionario.getFolhaPagamentoCollection() == null) {
            funcionario.setFolhaPagamentoCollection(new ArrayList<FolhaPagamento>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Usuario usuarioId = funcionario.getUsuarioId();
            if (usuarioId != null) {
                usuarioId = em.getReference(usuarioId.getClass(), usuarioId.getUsuarioId());
                funcionario.setUsuarioId(usuarioId);
            }
            List<Manutencao> attachedManutencaoCollection = new ArrayList<Manutencao>();
            for (Manutencao manutencaoCollectionManutencaoToAttach : funcionario.getManutencaoCollection()) {
                manutencaoCollectionManutencaoToAttach = em.getReference(manutencaoCollectionManutencaoToAttach.getClass(), manutencaoCollectionManutencaoToAttach.getManutencaoId());
                attachedManutencaoCollection.add(manutencaoCollectionManutencaoToAttach);
            }
            funcionario.setManutencaoCollection(attachedManutencaoCollection);
            List<Compra> attachedCompraCollection = new ArrayList<Compra>();
            for (Compra compraCollectionCompraToAttach : funcionario.getCompraCollection()) {
                compraCollectionCompraToAttach = em.getReference(compraCollectionCompraToAttach.getClass(), compraCollectionCompraToAttach.getCompraId());
                attachedCompraCollection.add(compraCollectionCompraToAttach);
            }
            funcionario.setCompraCollection(attachedCompraCollection);
            List<Venda> attachedVendaCollection = new ArrayList<Venda>();
            for (Venda vendaCollectionVendaToAttach : funcionario.getVendaCollection()) {
                vendaCollectionVendaToAttach = em.getReference(vendaCollectionVendaToAttach.getClass(), vendaCollectionVendaToAttach.getVendaId());
                attachedVendaCollection.add(vendaCollectionVendaToAttach);
            }
            funcionario.setVendaCollection(attachedVendaCollection);
            List<FolhaPagamento> attachedFolhaPagamentoCollection = new ArrayList<FolhaPagamento>();
            for (FolhaPagamento folhaPagamentoCollectionFolhaPagamentoToAttach : funcionario.getFolhaPagamentoCollection()) {
                folhaPagamentoCollectionFolhaPagamentoToAttach = em.getReference(folhaPagamentoCollectionFolhaPagamentoToAttach.getClass(), folhaPagamentoCollectionFolhaPagamentoToAttach.getFolhaPagamentoId());
                attachedFolhaPagamentoCollection.add(folhaPagamentoCollectionFolhaPagamentoToAttach);
            }
            funcionario.setFolhaPagamentoCollection(attachedFolhaPagamentoCollection);
            em.persist(funcionario);
            if (usuarioId != null) {
                usuarioId.getFuncionarioCollection().add(funcionario);
                usuarioId = em.merge(usuarioId);
            }
            for (Manutencao manutencaoCollectionManutencao : funcionario.getManutencaoCollection()) {
                manutencaoCollectionManutencao.getFuncionarioCollection().add(funcionario);
                manutencaoCollectionManutencao = em.merge(manutencaoCollectionManutencao);
            }
            for (Compra compraCollectionCompra : funcionario.getCompraCollection()) {
                Funcionario oldFuncionarioIdOfCompraCollectionCompra = compraCollectionCompra.getFuncionarioId();
                compraCollectionCompra.setFuncionarioId(funcionario);
                compraCollectionCompra = em.merge(compraCollectionCompra);
                if (oldFuncionarioIdOfCompraCollectionCompra != null) {
                    oldFuncionarioIdOfCompraCollectionCompra.getCompraCollection().remove(compraCollectionCompra);
                    oldFuncionarioIdOfCompraCollectionCompra = em.merge(oldFuncionarioIdOfCompraCollectionCompra);
                }
            }
            for (Venda vendaCollectionVenda : funcionario.getVendaCollection()) {
                Funcionario oldFuncionarioIdOfVendaCollectionVenda = vendaCollectionVenda.getFuncionarioId();
                vendaCollectionVenda.setFuncionarioId(funcionario);
                vendaCollectionVenda = em.merge(vendaCollectionVenda);
                if (oldFuncionarioIdOfVendaCollectionVenda != null) {
                    oldFuncionarioIdOfVendaCollectionVenda.getVendaCollection().remove(vendaCollectionVenda);
                    oldFuncionarioIdOfVendaCollectionVenda = em.merge(oldFuncionarioIdOfVendaCollectionVenda);
                }
            }
            for (FolhaPagamento folhaPagamentoCollectionFolhaPagamento : funcionario.getFolhaPagamentoCollection()) {
                Funcionario oldFuncionarioIdOfFolhaPagamentoCollectionFolhaPagamento = folhaPagamentoCollectionFolhaPagamento.getFuncionarioId();
                folhaPagamentoCollectionFolhaPagamento.setFuncionarioId(funcionario);
                folhaPagamentoCollectionFolhaPagamento = em.merge(folhaPagamentoCollectionFolhaPagamento);
                if (oldFuncionarioIdOfFolhaPagamentoCollectionFolhaPagamento != null) {
                    oldFuncionarioIdOfFolhaPagamentoCollectionFolhaPagamento.getFolhaPagamentoCollection().remove(folhaPagamentoCollectionFolhaPagamento);
                    oldFuncionarioIdOfFolhaPagamentoCollectionFolhaPagamento = em.merge(oldFuncionarioIdOfFolhaPagamentoCollectionFolhaPagamento);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Funcionario funcionario) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Funcionario persistentFuncionario = em.find(Funcionario.class, funcionario.getFuncionarioId());
            Usuario usuarioIdOld = persistentFuncionario.getUsuarioId();
            Usuario usuarioIdNew = funcionario.getUsuarioId();
            List<Manutencao> manutencaoCollectionOld = persistentFuncionario.getManutencaoCollection();
            List<Manutencao> manutencaoCollectionNew = funcionario.getManutencaoCollection();
            List<Compra> compraCollectionOld = persistentFuncionario.getCompraCollection();
            List<Compra> compraCollectionNew = funcionario.getCompraCollection();
            List<Venda> vendaCollectionOld = persistentFuncionario.getVendaCollection();
            List<Venda> vendaCollectionNew = funcionario.getVendaCollection();
            List<FolhaPagamento> folhaPagamentoCollectionOld = persistentFuncionario.getFolhaPagamentoCollection();
            List<FolhaPagamento> folhaPagamentoCollectionNew = funcionario.getFolhaPagamentoCollection();
            List<String> illegalOrphanMessages = null;
            for (Venda vendaCollectionOldVenda : vendaCollectionOld) {
                if (!vendaCollectionNew.contains(vendaCollectionOldVenda)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Venda " + vendaCollectionOldVenda + " since its funcionarioId field is not nullable.");
                }
            }
            for (FolhaPagamento folhaPagamentoCollectionOldFolhaPagamento : folhaPagamentoCollectionOld) {
                if (!folhaPagamentoCollectionNew.contains(folhaPagamentoCollectionOldFolhaPagamento)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain FolhaPagamento " + folhaPagamentoCollectionOldFolhaPagamento + " since its funcionarioId field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (usuarioIdNew != null) {
                usuarioIdNew = em.getReference(usuarioIdNew.getClass(), usuarioIdNew.getUsuarioId());
                funcionario.setUsuarioId(usuarioIdNew);
            }
            List<Manutencao> attachedManutencaoCollectionNew = new ArrayList<Manutencao>();
            for (Manutencao manutencaoCollectionNewManutencaoToAttach : manutencaoCollectionNew) {
                manutencaoCollectionNewManutencaoToAttach = em.getReference(manutencaoCollectionNewManutencaoToAttach.getClass(), manutencaoCollectionNewManutencaoToAttach.getManutencaoId());
                attachedManutencaoCollectionNew.add(manutencaoCollectionNewManutencaoToAttach);
            }
            manutencaoCollectionNew = attachedManutencaoCollectionNew;
            funcionario.setManutencaoCollection(manutencaoCollectionNew);
            List<Compra> attachedCompraCollectionNew = new ArrayList<Compra>();
            for (Compra compraCollectionNewCompraToAttach : compraCollectionNew) {
                compraCollectionNewCompraToAttach = em.getReference(compraCollectionNewCompraToAttach.getClass(), compraCollectionNewCompraToAttach.getCompraId());
                attachedCompraCollectionNew.add(compraCollectionNewCompraToAttach);
            }
            compraCollectionNew = attachedCompraCollectionNew;
            funcionario.setCompraCollection(compraCollectionNew);
            List<Venda> attachedVendaCollectionNew = new ArrayList<Venda>();
            for (Venda vendaCollectionNewVendaToAttach : vendaCollectionNew) {
                vendaCollectionNewVendaToAttach = em.getReference(vendaCollectionNewVendaToAttach.getClass(), vendaCollectionNewVendaToAttach.getVendaId());
                attachedVendaCollectionNew.add(vendaCollectionNewVendaToAttach);
            }
            vendaCollectionNew = attachedVendaCollectionNew;
            funcionario.setVendaCollection(vendaCollectionNew);
            List<FolhaPagamento> attachedFolhaPagamentoCollectionNew = new ArrayList<FolhaPagamento>();
            for (FolhaPagamento folhaPagamentoCollectionNewFolhaPagamentoToAttach : folhaPagamentoCollectionNew) {
                folhaPagamentoCollectionNewFolhaPagamentoToAttach = em.getReference(folhaPagamentoCollectionNewFolhaPagamentoToAttach.getClass(), folhaPagamentoCollectionNewFolhaPagamentoToAttach.getFolhaPagamentoId());
                attachedFolhaPagamentoCollectionNew.add(folhaPagamentoCollectionNewFolhaPagamentoToAttach);
            }
            folhaPagamentoCollectionNew = attachedFolhaPagamentoCollectionNew;
            funcionario.setFolhaPagamentoCollection(folhaPagamentoCollectionNew);
            funcionario = em.merge(funcionario);
            if (usuarioIdOld != null && !usuarioIdOld.equals(usuarioIdNew)) {
                usuarioIdOld.getFuncionarioCollection().remove(funcionario);
                usuarioIdOld = em.merge(usuarioIdOld);
            }
            if (usuarioIdNew != null && !usuarioIdNew.equals(usuarioIdOld)) {
                usuarioIdNew.getFuncionarioCollection().add(funcionario);
                usuarioIdNew = em.merge(usuarioIdNew);
            }
            for (Manutencao manutencaoCollectionOldManutencao : manutencaoCollectionOld) {
                if (!manutencaoCollectionNew.contains(manutencaoCollectionOldManutencao)) {
                    manutencaoCollectionOldManutencao.getFuncionarioCollection().remove(funcionario);
                    manutencaoCollectionOldManutencao = em.merge(manutencaoCollectionOldManutencao);
                }
            }
            for (Manutencao manutencaoCollectionNewManutencao : manutencaoCollectionNew) {
                if (!manutencaoCollectionOld.contains(manutencaoCollectionNewManutencao)) {
                    manutencaoCollectionNewManutencao.getFuncionarioCollection().add(funcionario);
                    manutencaoCollectionNewManutencao = em.merge(manutencaoCollectionNewManutencao);
                }
            }
            for (Compra compraCollectionOldCompra : compraCollectionOld) {
                if (!compraCollectionNew.contains(compraCollectionOldCompra)) {
                    compraCollectionOldCompra.setFuncionarioId(null);
                    compraCollectionOldCompra = em.merge(compraCollectionOldCompra);
                }
            }
            for (Compra compraCollectionNewCompra : compraCollectionNew) {
                if (!compraCollectionOld.contains(compraCollectionNewCompra)) {
                    Funcionario oldFuncionarioIdOfCompraCollectionNewCompra = compraCollectionNewCompra.getFuncionarioId();
                    compraCollectionNewCompra.setFuncionarioId(funcionario);
                    compraCollectionNewCompra = em.merge(compraCollectionNewCompra);
                    if (oldFuncionarioIdOfCompraCollectionNewCompra != null && !oldFuncionarioIdOfCompraCollectionNewCompra.equals(funcionario)) {
                        oldFuncionarioIdOfCompraCollectionNewCompra.getCompraCollection().remove(compraCollectionNewCompra);
                        oldFuncionarioIdOfCompraCollectionNewCompra = em.merge(oldFuncionarioIdOfCompraCollectionNewCompra);
                    }
                }
            }
            for (Venda vendaCollectionNewVenda : vendaCollectionNew) {
                if (!vendaCollectionOld.contains(vendaCollectionNewVenda)) {
                    Funcionario oldFuncionarioIdOfVendaCollectionNewVenda = vendaCollectionNewVenda.getFuncionarioId();
                    vendaCollectionNewVenda.setFuncionarioId(funcionario);
                    vendaCollectionNewVenda = em.merge(vendaCollectionNewVenda);
                    if (oldFuncionarioIdOfVendaCollectionNewVenda != null && !oldFuncionarioIdOfVendaCollectionNewVenda.equals(funcionario)) {
                        oldFuncionarioIdOfVendaCollectionNewVenda.getVendaCollection().remove(vendaCollectionNewVenda);
                        oldFuncionarioIdOfVendaCollectionNewVenda = em.merge(oldFuncionarioIdOfVendaCollectionNewVenda);
                    }
                }
            }
            for (FolhaPagamento folhaPagamentoCollectionNewFolhaPagamento : folhaPagamentoCollectionNew) {
                if (!folhaPagamentoCollectionOld.contains(folhaPagamentoCollectionNewFolhaPagamento)) {
                    Funcionario oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento = folhaPagamentoCollectionNewFolhaPagamento.getFuncionarioId();
                    folhaPagamentoCollectionNewFolhaPagamento.setFuncionarioId(funcionario);
                    folhaPagamentoCollectionNewFolhaPagamento = em.merge(folhaPagamentoCollectionNewFolhaPagamento);
                    if (oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento != null && !oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento.equals(funcionario)) {
                        oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento.getFolhaPagamentoCollection().remove(folhaPagamentoCollectionNewFolhaPagamento);
                        oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento = em.merge(oldFuncionarioIdOfFolhaPagamentoCollectionNewFolhaPagamento);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = funcionario.getFuncionarioId();
                if (findFuncionario(id) == null) {
                    throw new NonexistentEntityException("The funcionario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Funcionario funcionario;
            try {
                funcionario = em.getReference(Funcionario.class, id);
                funcionario.getFuncionarioId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The funcionario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Venda> vendaCollectionOrphanCheck = funcionario.getVendaCollection();
            for (Venda vendaCollectionOrphanCheckVenda : vendaCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Funcionario (" + funcionario + ") cannot be destroyed since the Venda " + vendaCollectionOrphanCheckVenda + " in its vendaCollection field has a non-nullable funcionarioId field.");
            }
            List<FolhaPagamento> folhaPagamentoCollectionOrphanCheck = funcionario.getFolhaPagamentoCollection();
            for (FolhaPagamento folhaPagamentoCollectionOrphanCheckFolhaPagamento : folhaPagamentoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Funcionario (" + funcionario + ") cannot be destroyed since the FolhaPagamento " + folhaPagamentoCollectionOrphanCheckFolhaPagamento + " in its folhaPagamentoCollection field has a non-nullable funcionarioId field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Usuario usuarioId = funcionario.getUsuarioId();
            if (usuarioId != null) {
                usuarioId.getFuncionarioCollection().remove(funcionario);
                usuarioId = em.merge(usuarioId);
            }
            List<Manutencao> manutencaoCollection = funcionario.getManutencaoCollection();
            for (Manutencao manutencaoCollectionManutencao : manutencaoCollection) {
                manutencaoCollectionManutencao.getFuncionarioCollection().remove(funcionario);
                manutencaoCollectionManutencao = em.merge(manutencaoCollectionManutencao);
            }
            List<Compra> compraCollection = funcionario.getCompraCollection();
            for (Compra compraCollectionCompra : compraCollection) {
                compraCollectionCompra.setFuncionarioId(null);
                compraCollectionCompra = em.merge(compraCollectionCompra);
            }
            em.remove(funcionario);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Funcionario> findFuncionarioEntities() {
        return findFuncionarioEntities(true, -1, -1);
    }

    public List<Funcionario> findFuncionarioEntities(int maxResults, int firstResult) {
        return findFuncionarioEntities(false, maxResults, firstResult);
    }

    private List<Funcionario> findFuncionarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Funcionario as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Funcionario findFuncionario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Funcionario.class, id);
        } finally {
            em.close();
        }
    }

    public int getFuncionarioCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from Funcionario as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
